package com.randi.system.service.impl;

import com.randi.common.config.AppConfig;
import com.randi.common.constant.CacheConstants;
import com.randi.common.core.domain.entity.SysMenu;
import com.randi.common.enums.ResultCode;
import com.randi.common.exception.ServiceException;
import com.randi.common.utils.ArrayUtils;
import com.randi.common.utils.TreeUtils;
import com.randi.system.domain.dto.RoleMenuDTO;
import com.randi.system.domain.entity.SysRoleMenu;
import com.randi.system.domain.params.SysMenuParam;
import com.randi.system.domain.vo.AuthMenu;
import com.randi.system.mapper.SysRoleMenuMapper;
import com.randi.system.service.ISysMenuService;
import com.randi.system.service.ISysRoleMenuService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author ziye
 */
@Service
@CacheConfig(cacheNames = CacheConstants.SYS_ROLE_MENU)
public class SysRoleMenuServiceImpl implements ISysRoleMenuService {

    @Resource
    private ISysMenuService iSysMenuService;

    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Resource
    private AppConfig.SystemConfig systemConfig;


    /**
     * 获取授权菜单树
     *
     * @return 授权菜单树
     */
    @Override
//    @Cacheable(key = "'tree'")
    public List<AuthMenu> selectAllocatedMenuTree() {
        List<SysMenu> sysMenuList = iSysMenuService.selectSysMenuList(new SysMenuParam());
        List<AuthMenu> authMenuList = sysMenuList.stream()
                .map(AuthMenu::new)
                .collect(Collectors.toList());

        return TreeUtils.buildTree(authMenuList);
    }

    /**
     * 获取已授权菜单ID
     *
     * @param roleId 角色ID
     * @return 菜单ID集合
     */
    @Override
    @Cacheable(key = "#roleId", unless = "#result == null or #result.isEmpty()")
    public List<Long> selectAllocatedMenu(Long roleId) {
        return sysRoleMenuMapper.selectSysRoleMenuListByRoleId(roleId);
    }

    /**
     * 修改角色菜单
     *
     * @param roleMenuDTO 授权菜单参数
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true, beforeInvocation = true)
    public int updateRoleMenu(RoleMenuDTO roleMenuDTO) {
        Long roleId = roleMenuDTO.getRoleId();
        if (roleId.equals(systemConfig.getRoleAdminId())) {
            throw new ServiceException(ResultCode.BUSINESS_ROLE_AUTH_ERROR_ADMIN);
        }

        List<Long> original = sysRoleMenuMapper.selectSysRoleMenuListByRoleId(roleId);
        List<Long> current = roleMenuDTO.getMenuIds();

        List<Long> deleteList = ArrayUtils.difference(original, current);

        int status = 0;
        if (!deleteList.isEmpty()) {
            status += sysRoleMenuMapper.deleteBatch(roleId, deleteList);
        }

        List<SysRoleMenu> insertList = ArrayUtils.difference(current, original).stream()
                .map(menuId -> new SysRoleMenu(roleId, menuId))
                .collect(Collectors.toList());

        if (!insertList.isEmpty()) {
            status += sysRoleMenuMapper.insertBatch(insertList);
        }

        return status == 0L ? -1 : status;
    }

}
